<?php

namespace Shenlink\Holiya\Console;

use Shenlink\Holiya\Console\Command\ICommand;
use Shenlink\Holiya\Console\Command\HelpCommand;
use Shenlink\Holiya\Console\Command\PushCommand;
use Shenlink\Holiya\Console\Command\TestCommand;
use Shenlink\Holiya\Console\Command\VersionCommand;

/**
 * 控制台应用程序类
 *
 * 负责管理命令行工具的所有命令和执行流程
 */
class Application
{
    /**
     * 已注册的命令列表
     *
     * @var array<string, ICommand>
     */
    private array $commands = [];

    /**
     * 应用程序名称
     *
     * @var string
     */
    private string $name;

    /**
     * 应用程序版本
     *
     * @var string
     */
    private string $version;

    /**
     * Application 构造函数
     *
     * @param string $name 应用程序名称
     * @param string $version 应用程序版本
     */
    public function __construct(string $name = 'Holiya Console', string $version = '1.0.0')
    {
        $this->name = $name;
        $this->version = $version;

        // 注册默认命令
        $this->addCommand(new TestCommand());
        $this->addCommand(new VersionCommand());
        $this->addCommand(new PushCommand());

        // 帮助命令需要引用所有已注册的命令
        $this->addCommand(new HelpCommand($this->commands));
    }

    /**
     * 添加命令到应用中
     *
     * @param ICommand $command 要添加的命令
     * @return void
     */
    public function addCommand(ICommand $command): void
    {
        $this->commands[$command->getName()] = $command;
    }

    /**
     * 运行应用程序
     *
     * @param array $argv 命令行参数
     * @return int 执行结果状态码
     */
    public function run(array $argv): int
    {
        if (count($argv) < 2) {
            $this->showHelp();
            return 0;
        }

        $commandName = $argv[1];
        $arguments = array_slice($argv, 2);

        // 处理特殊参数
        if (in_array($commandName, ['-v', '--version'])) {
            $commandName = 'version';
        } elseif (in_array($commandName, ['-h', '--help', 'help']) && empty($arguments)) {
            $commandName = 'help';
        }

        if (!isset($this->commands[$commandName])) {
            echo "未知命令: $commandName\n\n";
            $this->showHelp();
            return 1;
        }

        $command = $this->commands[$commandName];

        // 检查是否有 help 参数
        if (in_array('--help', $arguments) || in_array('-h', $arguments)) {
            $command->showHelp();
            return 0;
        }

        return $command->execute($arguments);
    }

    /**
     * 显示帮助信息
     *
     * @return void
     */
    private function showHelp(): void
    {
        /** @var HelpCommand $helpCommand */
        $helpCommand = $this->commands['help'];
        $helpCommand->execute();
    }
}